package 线程不安全;

import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class HashMapThreadUnsafe {
    public static void main(String[] args) throws InterruptedException {

        // 1.并发修改导致数据不一致
        final HashMap<String, Integer> map = new HashMap<>(2, 0.75f);

        Thread t1 = new Thread(() -> {
           for (int i = 0; i < 10000; i++) {
               map.put("key" + i, i);
           }
        });
        Thread t2 = new Thread(() -> {
           for (int i = 0; i < 10000; i++) {
               map.put("key" + i, i * 2);
           }
        });

        t1.start();
        t2.start();

        t1.join();// 等待t1线程结束
        t2.join();// 等待t2线程结束
        map.forEach((k, v) -> {
            System.out.println("k => " + k + ", v = " + v);
        });
        System.out.println("map.size => " + map.size()); // 10446


        System.out.println("----------------------------------------");
        // 2.并发扩容导致死循环或数据丢失
        // 初始化大小为2，负载因子为0.75；当元素数量达到3时就会进行扩容操作
        final Map<String, Integer> map2 = new HashMap<>(2, 0.75f);
        map2.put("key1", 1);
        map2.put("key2", 2);
        map2.put("key3", 3);
        Thread t3 = new Thread(() -> {
           for (int i = 4; i < 1000; i++) {
               map2.put("key" + i, i);
           }
        });
        Thread t4 = new Thread(() -> {
            for (int i = 4; i < 10000; i++) {
                map2.put("key" + i, i * 2);
            }
        });
        t3.start();
        t4.start();
        t3.join();
        t4.join();
        System.out.println("map2.size => " + map2.size()); // 10159


        System.out.println("----------------------------------------");
        // 3.非线程安全的迭代器
        final Map<String, Integer> map3 = new HashMap<>();
        for (int i = 0; i < 10000; i++) {
            map3.put("key" + i, i);
        }
//        Thread t5 = new Thread(() -> {
//            Iterator<Map.Entry<String, Integer>> iterator = map3.entrySet().iterator();
//            while (iterator.hasNext()) {
//                System.out.println(iterator.next().getKey() + " => " + iterator.next().getValue());// ConcurrentModificationException
//            }
//        });
        Thread t6 = new Thread(() -> {
            for (int i = 10000; i < 20000; i++) {
                map3.put("key" + i, i);
            }
        });
//        t5.start();
        t6.start();
//        t5.join();
        t6.join();
        System.out.println("map3.size => " + map3.size());


        System.out.println("--------------------------------------");
        // 4.非线程安全的比较器
        final Map<String, Integer> map4 = new HashMap<>(16, 0.75f);
        for (int i = 1; i <= 3; i++) {
            map4.put("key" + i, i);
        }
        Comparator<String> comparator = (s1, s2) -> {
            int i1 = Integer.parseInt(s1.substring(3));
            int i2 = Integer.parseInt(s2.substring(3));
            return Integer.compare(i1, i2);
        };

        Thread t7 = new Thread(() -> {
            for (int i = 4; i < 10000; i++) {
                map4.put("key" + i, i);
            }
        });
        Thread t8 = new Thread(() -> {
            for (int i = 4; i < 10000; i++) {
                map4.put("key" + i, i * 2);
            }
        });
        t7.start();
        t8.start();
        t7.join();
        t8.join();
        System.out.println("map4.size => " + map4.size());
    }
}
